/*****************************************************************************
 * $LastChangedDate: 2011-09-25 12:03:59 -0400 (Sun, 25 Sep 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Sound class (SDL).
 *//*
 * LEGAL:   COPYRIGHT (C) 2009 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#if COMPILE_SDL_MIXER
#ifndef SOUND_SOUND_SDL_HH
#define SOUND_SOUND_SDL_HH 1

#include "base/singleton.hh"

//------------------------------------------------------------------------------
namespace sound {
namespace defs {

const int SOUND_SDL_INVALID_CHANNEL = -1;
const int SOUND_SDL_FREQ            = 22050;
const int SOUND_SDL_FORMAT          = MIX_DEFAULT_FORMAT;
const int SOUND_SDL_STEREO_OR_MONO  = 2;  // or 1 for mono
const int SOUND_SDL_CHUNK_SIZE      = 0x1000;

} // namespace defs
} // namespace sound
//------------------------------------------------------------------------------

#include "base/singleton.hh"
#include "sound/sound_base.hh"
#include "sound/sound_sample.hh"

namespace sound {

void PRINT_SDL_ERROR( void );

////////////////////////////////////////////////////////////////////////////////
/// @brief Sound class (SDL).
///
/// Class design:
/// -------------
/// See SoundBase.
///
/// SoundSDL class:
/// ---------------
/// SDL_mixer is used.
/// The SDL_RWop mechanism is used to read gzip-compressed sound files.
/// SoundSDL creates either a SampleSDLWave or SampleSDLMusic object
/// according to the kind of sound file.
/// Difference between WAV/MUS is how many and which channels are used.
///
/// SDL wave vs. music, SDL misnomers:
/// ----------------------------------
/// Wave means a sample/chunk.
/// A SDL wave object is bound to a channel.
/// A SDL music object isn't.
/// Whether a sound file is a wave or music is determined
/// when trying to use a SDL WAV() or MUS() function.
/// SDL sound functions are misnomers, for example,
/// SDL_*WAV() can load OGG etc music files too.
///
/// SDL's underlying sound libraries:
/// ---------------------------------
/// [2009/12]
/// What works well:
///     Playing WAV and OGG.
/// What doesn't:
///     Note that SDL_mixer is linked with various OPTIONAL LIBRARIES.
///     The underlying SMPEG library is flakey and won't play all kinds of MPEGs.
///     Playing MIDI does work well but requires timidity.
///     On Debian 5 Linux, timidity has to run as a daemon.
/// Summary:
///     Prefer .wav since SDL_mixer contains WAV code.
///     Per the code of Mix_LoadWAV_RW(), no other kinds of sound is intrinsic.
///
class SoundSDL : public SoundBase, public Singleton
{
PREVENT_COPYING(SoundSDL)
private:
            SoundSDL( void );
    virtual ~SoundSDL();

public:
                            DEFINE_GetInstance( SoundSDL )  // Singleton
    virtual bool            Enable( const bool enable = true );
    virtual bool            IfEnabled( void ) { return mEnabled; }
    virtual fp              GetVolume( void );
    virtual bool            SetVolume( const fp volume );  // master volume
    // [SoundBase defines the other methods]

private:
    virtual shptr<Sample>   CreateSample( const Sample::Name& sampleName );

private:
    DECLARE_SINGLETON_CLASS_VARS( SoundSDL )
    bool    mEnabled;
    bool    mWasEnabled;    ///< true if sound was ever enabled before
    fp      mVolume;        ///< master volume
};

} // namespace sound

#endif // SOUND_SOUND_SDL_HH
#endif // COMPILE_SDL_MIXER
